import * as CryptoJS from 'crypto-js';
import { sm4 } from 'sm-crypto';
import { validateNull } from './validate';

/**
 *加密处理
 */
export function encryption(src: string, keyWord: string) {
  const key = CryptoJS.enc.Utf8.parse(keyWord);
  // 加密
  var encrypted = CryptoJS.AES.encrypt(src, key, {
    iv: key,
    mode: CryptoJS.mode.CFB,
    padding: CryptoJS.pad.NoPadding,
  });
  return encrypted.toString();
}

/**
 *  解密
 * @param {*} params 参数列表
 * @returns 明文
 */
export function decryption(src: string, keyWord: string) {
  const key = CryptoJS.enc.Utf8.parse(keyWord);
  // 解密逻辑
  var decryptd = CryptoJS.AES.decrypt(src, key, {
    iv: key,
    mode: CryptoJS.mode.CFB,
    padding: CryptoJS.pad.NoPadding,
  });

  return decryptd.toString(CryptoJS.enc.Utf8);
}

/**
 * SM4加密处理
 */
export function sm4Encryption(src: string, keyWord: string) {
  return sm4.encrypt(src, keyWord);
}

/**
 * SM4解密处理
 * @param {*} params 参数列表
 * @returns 明文
 */
export function sm4Decryption(src: string, keyWord: string) {
  return sm4.decrypt(src, keyWord);
}

/**
 * Base64 加密
 * @param {*} src  明文
 * @returns 密文
 */
export function base64Encrypt(src: String) {
  const encodedWord = CryptoJS.enc.Utf8.parse(src);
  return CryptoJS.enc.Base64.stringify(encodedWord);
}

/**
 * @description 生成唯一 uuid
 * @return string
 */
export function generateUUID() {
  if (typeof crypto === 'object') {
    if (typeof crypto.randomUUID === 'function') {
      return crypto.randomUUID();
    }
    if (typeof crypto.getRandomValues === 'function' && typeof Uint8Array === 'function') {
      const callback = (c: any) => {
        const num = Number(c);
        return (num ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (num / 4)))).toString(
          16
        );
      };
      return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, callback);
    }
  }
  let timestamp = new Date().getTime();
  let performanceNow =
    (typeof performance !== 'undefined' && performance.now && performance.now() * 1000) || 0;
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    let random = Math.random() * 16;
    if (timestamp > 0) {
      random = (timestamp + random) % 16 | 0;
      timestamp = Math.floor(timestamp / 16);
    } else {
      random = (performanceNow + random) % 16 | 0;
      performanceNow = Math.floor(performanceNow / 16);
    }
    return (c === 'x' ? random : (random & 0x3) | 0x8).toString(16);
  });
}

/**
 *
 * @param str 驼峰转下划线
 * @returns 下划线
 */
export function toUnderline(str: string) {
  return str.replace(/([A-Z])/g, '_$1').toLowerCase();
}

/**
 * 自动适配不同的后端架构
 * 1. 例如 /act/oa/task ,在微服务架构保持不变,在单体架构编程 /admin/oa/task
 * 2. 特殊 /gen/xxx ,在微服务架构、单体架构编程 都需保持不变
 *
 * @param originUrl 原始路径
 */
export const adaptationUrl = (originUrl?: string) => {
  // 微服务架构 不做路径转换,为空不做路径转换
  const isMicro = import.meta.env.VITE_IS_MICRO;
  console.log('isMicro-', isMicro, originUrl); // typeof isMicro: string
  if (validateNull(isMicro) || isMicro === 'true') {
    return originUrl;
  }

  // 转为 /admin 路由前缀的请求
  return `/admin/${originUrl?.split('/').splice(2).join('/')}`;
};

/**
 * @description 获取不重复的id
 * @param length { Number } id的长度
 * @return { String } id
 */
export const getNonDuplicateID = (length = 8) => {
  let idStr = Date.now().toString(36);
  idStr += Math.random().toString(36).substring(3, length);
  return idStr;
};

/**
 * @description 添加单位
 * @param {String | Number} value 值 100
 * @param {String} unit 单位 px em rem
 */
export const addUnit = (value: string | number, unit = 'px') => {
  return !Object.is(Number(value), NaN) ? `${value}${unit}` : value;
};

// 创建一个other对象，包含所有需要导出的函数
const other = {
  encryption,
  decryption,
  sm4Encryption,
  sm4Decryption,
  base64Encrypt,
  generateUUID,
  toUnderline,
  adaptationUrl,
  getNonDuplicateID,
  addUnit,
};

// 统一批量导出
export default other;
